class WxRequest {
  defaults = {
    baseURL: '',
    url: '',
    method: 'GET',
    data: null,
    useLoading: true,
    header: {
      'Content-Type': 'application/json'
    },
    timeout: 60000// 小程序里默认就是1分钟。
  }

  timerId = 0
  queue = []

  // 请求和响应拦截器
  interceptors = {
    request: (config) => config,
    response: (response) => response
  }

  constructor(params = {}) {
    this.defaults = Object.assign({}, this.defaults, params)
  }

  request(options) {
    this.timerId && clearTimeout(this.timerId)

    options.url = this.defaults.baseURL + options.url
    options = { ...this.defaults, ...options }
    options = this.interceptors.request(options)
    
    // 上传文件自带 loading 效果
    let enableLoading = options.useLoading && options.method !== 'UPLOAD'

    if (enableLoading) {
      this.queue.length === 0 && wx.showLoading()
      this.queue.push('request')
    }

    return new Promise((resolve, reject) => {
      if (options.method === 'UPLOAD') {
        wx.uploadFile({
          ...options,

          success: (response) => {
            response.data = JSON.parse(response.data)
            resolve(this.interceptors.response(Object.assign({}, response, { config: options, isSuccess: true })))
          },

          fail: (err) => {
            resolve(this.interceptors.response(Object.assign({}, err, { config: options, isSuccess: false })))
          }
        })
      } else {
        wx.request({
          ...options,

          success: (response) => {
            resolve(this.interceptors.response(Object.assign({}, response, { config: options, isSuccess: true })))
          },
          fail: (err) => {
            reject(this.interceptors.response(Object.assign({}, err, { config: options, isSuccess: false })))
          },
          complete: () => {

            if (enableLoading) {
              this.queue.pop()
              this.queue.length === 0 && this.queue.push('request')

              // 解决网络请求过快导致的闪屏问题
              this.timerId = setTimeout(() => {
                this.queue.pop()
                this.queue.length === 0 && wx.hideLoading()
                clearTimeout(this.timerId)
              }, 1)
            }
          }
        }) 
      }
    })
  }

  get(url, data = {}, config = {}) {
    return this.request(Object.assign({url, data, method: 'GET'}, config))
  }

  post(url, data = {}, config = {}) {
    return this.request(Object.assign({url, data, method: 'POST'}, config))
  }

  delete(url, data = {}, config = {}) {
    return this.request(Object.assign({url, data, method: 'DELETE'}, config))
  }

  put(url, data = {}, config = {}) {
    return this.request(Object.assign({url, data, method: 'PUT'}, config))
  }

  // 并发请求
  all(...promises) {
    return Promise.all(promises)
  }

  // 上传文件
  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({ url, filePath, name, method: 'UPLOAD' }, config)
    )
  }
}

export default WxRequest
